package com.chaochis.springboottestdemo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chaochis.springboottestdemo.config.reqResConfig.dispatcherConfig.CustomRequestWrapper;
import com.chaochis.springboottestdemo.enumList.DataStatus;
import com.chaochis.springboottestdemo.mapper.UserMapper;
import com.chaochis.springboottestdemo.model.commonModel.LoginUserVo;
import com.chaochis.springboottestdemo.model.mapperModel.UserVo;
import com.chaochis.springboottestdemo.model.queryParam.LoginParam;
import com.chaochis.springboottestdemo.model.serviceModel.JwtToken;
import com.chaochis.springboottestdemo.service.CacheRedisLoginService;
import com.chaochis.springboottestdemo.service.JwtTokenService;
import com.chaochis.springboottestdemo.service.UserLoginService;
import com.chaochis.springboottestdemo.util.EncryptionUtil;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.Random;

@Service("userLoginService")
public class UserLoginServiceImpl implements UserLoginService {

  private final UserMapper userMapper;

  private final JwtTokenService jwtTokenService;

  private final CacheRedisLoginService cacheRedisLoginService;

  public UserLoginServiceImpl(UserMapper userMapper,
                              JwtTokenService jwtTokenService, CacheRedisLoginService cacheRedisLoginService) {
    this.userMapper = userMapper;
    this.jwtTokenService = jwtTokenService;
    this.cacheRedisLoginService = cacheRedisLoginService;
  }

  @Override
  public LoginUserVo login(CustomRequestWrapper customRequestWrapper, LoginParam userParam) throws Exception {
    var userName = userParam.getUserName();
    var userVo = this.getUserByUserName(userName);
    if (userVo == null) {
      throw new Exception("未找到该用户!");
    }
    if (!DataStatus.Normal.equals(userVo.getStatus())) {
      throw new Exception("该用户已" + userVo.getStatus().getText());
    }
    var encryptPassword = EncryptionUtil.encrypt(userParam.getPassword(), userVo.getSalt());
    if (!encryptPassword.equals(userVo.getPassword())) {
      throw new Exception("用户密码不对!");
    }
    var loginUserVo = new LoginUserVo();
    loginUserVo.setUserVo(userVo);
    var token = this.jwtTokenService.generateJwtTokenString(userVo, Duration.ofDays(12));
    loginUserVo.setToken(token);
    var jwtToken = JwtToken.build(token);
    this.cacheRedisLoginService.cacheLoginUserInfo(customRequestWrapper, jwtToken, loginUserVo);
    this.updateUserByChangeSalt(userVo, userParam);
    return loginUserVo;
  }

  void updateUserByChangeSalt (UserVo userVo, LoginParam loginParam) {
    var updateUserVo = new UserVo();
    var newSalt = String.valueOf(new Random().nextDouble());
    var newEncryptPassword = EncryptionUtil.encrypt(loginParam.getPassword(), newSalt);
    updateUserVo.setId(userVo.getId());
    updateUserVo.setSalt(newSalt);
    updateUserVo.setPassword(newEncryptPassword);
    this.userMapper.updateById(updateUserVo);
  }

  private UserVo getUserByUserName(String userName) {
    var userVo = new UserVo();
    userVo.setUserName(userName);
    return this.userMapper.selectOne(new QueryWrapper<>(userVo));
  }
}
